package com.oracle.lingshangejia.utils;

import android.annotation.TargetApi;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;

/**
 * Created by Hang.Yang on 2018/7/24 11:42.
 * If you find a path with no obstacles, it probably doesn’t lead anywhere.
 * In LongCaiHaErBin
 */

public class ConventionalUtils {

    /**
     * 判断一个字符串中是否包含有Emoji表情
     * @param input
     * @return true 有Emoji
     */
    public static boolean isEmojiCharacter(CharSequence input)
    {
        for (int i = 0; i < input.length(); i++)
        {
            if (isEmojiCharacter(input.charAt(i)))
            {
                return true;
            }
        }
        return false;
    }

    /**
     * 是否是Emoji 表情,抄的那哥们的代码
     *
     * @param codePoint
     * @return true 是Emoji表情
     */
    private static boolean isEmojiCharacter(char codePoint)
    {
        // Emoji 范围
        boolean isScopeOf = (codePoint == 0x0) || (codePoint == 0x9) || (codePoint == 0xA) || (codePoint == 0xD)
                || ((codePoint >= 0x20) && (codePoint <= 0xD7FF) && (codePoint != 0x263a))
                || ((codePoint >= 0xE000) && (codePoint <= 0xFFFD))
                || ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF));

        return !isScopeOf;
    }

    public static String listToStringseparated(List<String> stringList){
        if (stringList==null) {
            return null;
        }
        StringBuilder result=new StringBuilder();
        boolean flag=false;
        for (String string : stringList) {
            if (flag) {
                result.append(",");
            }else {
                flag=true;
            }
            result.append(string);
        }
        return result.toString();
    }

    public static String listToString(List<String> stringList){
        if (stringList==null) {
            return null;
        }
        StringBuilder result=new StringBuilder();
        for (String string : stringList) {
            result.append(string);
        }
        return result.toString();
    }

    public static List<String> stringToList(String strs){

        String str[] = strs.split(",");

        return Arrays.asList(str);
    }

    //计算时间 往前倒  往后倒
    public static String getCalculateDate() {

        List<String> list_month = new ArrayList<>();

        Calendar c = Calendar.getInstance(); // 当时的日期和时间

        for (int i = 0; i < 12; i++) {

            if (i == 0){

                c.set(Calendar.MONTH, c.get(Calendar.MONTH));
            }else {

                c.set(Calendar.MONTH, c.get(Calendar.MONTH) - 1);
            }

            int mYear = c.get(Calendar.YEAR);
            int mMonth = c.get(Calendar.MONTH);
            int mDay = c.get(Calendar.DAY_OF_MONTH);
//            StringBuilder strForwardDate = new StringBuilder().append(mYear).append(
//                    (mMonth + 1) < 10 ? "0" + (mMonth + 1) : (mMonth + 1)).append(
//                    (mDay < 10) ? "0" + mDay : mDay);

            list_month.add(mYear + "-" + ((mMonth + 1) < 10 ? "0"  + (mMonth + 1) : (mMonth + 1)));
        }

        return listToStringseparated(list_month);

    }

    /**
     * 时间戳转日期
     * @param milSecond
     * @return
     */
    public static String getDateToString(long milSecond, String pattern) {
        Date date = new Date(milSecond* 1000);
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        return format.format(date);
    }

    /**
     * 日期转时间戳
     * @param dateString
     * @param pattern
     * @return
     */
    private long getStringToDate(String dateString, String pattern) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
        Date date = new Date();
        try{
            date = dateFormat.parse(dateString);
        } catch(ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return date.getTime()/1000;
    }

    //是否是手机号
    public static boolean isPhone(String phone){

        if (phone.length() == 11 && phone.substring(0,1).equals("1") && !phone.substring(1,2).equals("1") && !phone.substring(1,2).equals("0")){

            return false;
        }

        return true;
    }

    //密码是否规范
    public static boolean isPass(String pass){

        if (isChinese(pass) || isEmojiCharacter(pass) || pass.contains(" ")){

            return true;
        }

        return false;
    }

    //金额限制
    public static boolean isAmount(String amount){

        boolean istrue = false;

        for (int i = 0; i < amount.length(); i++) {

            if (!amount.substring(i,i + 1).equals(".") && !amount.substring(i,i + 1).equals("0")){

                istrue =  true;
            }
        }

        if ((!amount.contains(".") && amount.substring(0,1).equals("0")) ||
                (amount.substring(amount.length() - 1,amount.length()).equals(".")) ||
                (amount.substring(0,1).equals("0") && !amount.substring(1,2).equals(".")) ||
                !istrue){

            return true;
        }

        return false;
    }

    /**
     * 统计一个字符在字符串中出现的次数
     *
     * @param s 字符串
     * @param c 字符
     * @return 數量
     */
    public static int counter(String s, char c) {
        int count = 0;
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == c) {
                count++;
            }
        }
        return count;
    }

    // 判断一个字符是否是中文
    public static boolean isChinese(char c) {
        return c >= 0x4E00 && c <= 0x9FA5;// 根据字节码判断
    }

    // 判断一个字符串是否含有中文
    public static boolean isChinese(String str) {
        if (str == null)
            return false;
        for (char c : str.toCharArray()) {
            if (isChinese(c))
                return true;// 有一个中文字符就返回
        }
        return false;
    }

    // 判断一个字符串是否全是中文
    public static boolean isAllChinese(String str) {
        if (str == null)
            return false;
        for (char c : str.toCharArray()) {
            if (!isChinese(c))
                return true;// 有一个非中文字符就返回
        }
        return false;
    }

    //图片地址转base64
    public static String encodeBase64File(String path) throws Exception {
        File file = new File(path);
        FileInputStream inputFile = new FileInputStream(file);
        byte[] buffer = new byte[(int)file.length()];
        inputFile.read(buffer);
        inputFile.close();
        return Base64.encodeToString(buffer, Base64.DEFAULT);
    }

    //图片地址转stream
    public static byte[] encodePath2Stream(String path) throws Exception {
        File file = new File(path);
        InputStream inputFile = new FileInputStream(file);
        byte[] buffer = new byte[(int)file.length()];
        int len = 0;
        int curLen = 0;
        while ((len = inputFile.read(buffer)) != -1) {
            curLen += len;
            inputFile.read(buffer);
        }
        inputFile.close();
        return buffer;
    }

    /**
     * 获取版本信息
     * @param context
     * @return
     */
    public static int getVersionCode(Context context) {
        PackageManager manager = context.getPackageManager();
        int code = 0;
        try {
            PackageInfo info = manager.getPackageInfo(context.getPackageName(), 0);
            code = info.versionCode;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return code;
    }

    /**
     * 获取版本名
     * @param context
     * @return
     */
    public static String getVersionName(Context context) {
        PackageManager manager = context.getPackageManager();
        String name = null;
        try {
            PackageInfo info = manager.getPackageInfo(context.getPackageName(), 0);
            name = info.versionName;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }

        return name;
    }

    /**
     * 版本号比较
     *
     * @param version1
     * @param version2
     * @return
     */
    public static int compareVersion(String version1, String version2) {
        if (version1.equals(version2)) {
            return 0;
        }
        String[] version1Array = version1.split("\\.");
        String[] version2Array = version2.split("\\.");
        Log.d("HomePageActivity", "version1Array=="+version1Array.length);
        Log.d("HomePageActivity", "version2Array=="+version2Array.length);
        int index = 0;
        // 获取最小长度值
        int minLen = Math.min(version1Array.length, version2Array.length);
        int diff = 0;
        // 循环判断每位的大小
        Log.d("HomePageActivity", "verTag2=2222="+version1Array[index]);
        while (index < minLen
                && (diff = Integer.parseInt(version1Array[index])
                - Integer.parseInt(version2Array[index])) == 0) {
            index++;
        }
        if (diff == 0) {
            // 如果位数不一致，比较多余位数
            for (int i = index; i < version1Array.length; i++) {
                if (Integer.parseInt(version1Array[i]) > 0) {
                    return 1;
                }
            }

            for (int i = index; i < version2Array.length; i++) {
                if (Integer.parseInt(version2Array[i]) > 0) {
                    return -1;
                }
            }
            return 0;
        } else {
            return diff > 0 ? 1 : -1;
        }
    }

    /**
     * 手机中是否装有微信
     * @param context
     * @return
     */
    public static boolean isWeixinAvilible(Context context) {
        final PackageManager packageManager = context.getPackageManager();// 获取packagemanager
        List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);// 获取所有已安装程序的包信息
        if (pinfo != null) {
            for (int i = 0; i < pinfo.size(); i++) {
                String pn = pinfo.get(i).packageName;
                if (pn.equals("com.tencent.mm")) {
                    return true;
                }
            }
        }

        return false;
    }

    //验证身份证号是否正确
    public static final String[] ValCodeArr = { "1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2" };
    public static final String[] Wi = { "7", "9", "10", "5", "8", "4", "2", "1", "6", "3", "7", "9", "10", "5", "8", "4", "2" };
    // 身份证的最小出生日期,1900年1月1日
    private final static Date MINIMAL_BIRTH_DATE = new Date(-2209017600000L);
    private static final String BIRTH_DATE_FORMAT="yyyyMMdd";
    private final static int NEW_CARD_NUMBER_LENGTH = 18;
    private final static int OLD_CARD_NUMBER_LENGTH = 15;
    private final static String LENGTH_ERROR="身份证长度必须为15或者18位！";
    private final static String NUMBER_ERROR="15位身份证都应该为数字，18位身份证都应该前17位应该都为数字！";
    private final static String DATE_ERROR="身份证日期验证无效！";
    private final static String AREA_ERROR="身份证地区编码错误!";
    private final static String CHECKCODE_ERROR="身份证最后一位校验码有误！";
    //是否需要返回自动补全成的身份证
    private static boolean isNeedReturn_AutoCard=false;

    /**
     *
     * @param idcardNumber 需要验证的身份证
     * @param isreturn_AutoCard 验证无误后，是否需要返回自动补全身份证
     * @return 身份证无误返回传入的身份证号
     */
    public static boolean validate_effective(String idcardNumber, boolean isreturn_AutoCard){
        isNeedReturn_AutoCard=isreturn_AutoCard;
        return validate_effective(idcardNumber);
    }
    /**
     * 身份证校验
     * @param idcardNumber 需要验证的身份证
     * @return 身份证无误返回传入的身份证号
     */
    public static boolean validate_effective(String idcardNumber){
        String Ai=idcardNumber.trim();
        System.out.println(Ai.length()!=15);
        if(Ai.length()==15|Ai.length()==18){
            //如果为15位则自动补全到18位
            if(Ai.length()==OLD_CARD_NUMBER_LENGTH){
                Ai=contertToNewCardNumber(Ai);
            }
        }else{
            //LENGTH_ERROR
            return false;
        }
        // 身份证号的前15,17位必须是阿拉伯数字
        for (int i = 0;  i < NEW_CARD_NUMBER_LENGTH - 1; i++) {
            char ch = Ai.charAt(i);
            if( ch < '0' || ch > '9'){return false;}
        }
        //校验身份证日期信息是否有效 ，出生日期不能晚于当前时间，并且不能早于1900年
        try {
            Date birthDate =getBirthDate(Ai);
            if(null == birthDate){
                //DATE_ERROR
                return false;
            }
            if(!birthDate.before(new Date())){
                //DATE_ERROR
                return false;
            }
            if(!birthDate.after(MINIMAL_BIRTH_DATE)){
                //DATE_ERROR
                return false;
            }
            /**
             * 出生日期中的年、月、日必须正确,比如月份范围是[1,12],日期范围是[1,31]，还需要校验闰年、大月、小月的情况时，
             * 月份和日期相符合
             */
            String birthdayPart = getBirthDayPart(Ai);
            String realBirthdayPart =createBirthDateParser().format(birthDate);
            if(!birthdayPart.equals(realBirthdayPart)){
                //DATE_ERROR
                return false;
            }
        } catch (Exception e) {
            //DATE_ERROR
            return false;
        }
        //校验地区码是否正确
        Hashtable<String, String> h = GetAreaCode();
        if (h.get(Ai.substring(0, 2)) == null) {
            //AREA_ERROR
            return false;
        }
        //校验身份证最后一位 身份证校验码
        if(!calculateVerifyCode(Ai) .equals(String.valueOf(Ai.charAt(NEW_CARD_NUMBER_LENGTH - 1)))){
            //CHECKCODE_ERROR
            return false;
        }
        //通过验证则返回true
        return true;
    }

    /**
     * 把15位身份证号码转换到18位身份证号码<br>
     * 15位身份证号码与18位身份证号码的区别为：<br>
     * 1、15位身份证号码中，"出生年份"字段是2位，转换时需要补入"19"，表示20世纪<br>
     * 2、15位身份证无最后一位校验码。18位身份证中，校验码根据根据前17位生成
     *
     *
     * @return
     */
    private static String contertToNewCardNumber(String oldCardNumber) {
        StringBuilder buf = new StringBuilder(NEW_CARD_NUMBER_LENGTH);
        buf.append(oldCardNumber.substring(0, 6));
        buf.append("19");
        buf.append(oldCardNumber.substring(6));
        buf.append(calculateVerifyCode(buf));
        return buf.toString();
    }
    /**计算最后一位校验码  加权值%11
     * （1）十七位数字本体码加权求和公式 S = Sum(Ai * Wi), i = 0, ... , 16 ，先对前17位数字的权求和
     *      Ai:表示第i位置上的身份证号码数字值 Wi:表示第i位置上的加权因子 Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4
     * （2）计算模 Y = mod(S, 11)
     * （3）通过模得到对应的校验码 Y: 0 1 2 3 4 5 6 7 8 9 10 校验码: 1 0 X 9 8 7 6 5 4 3 2
     * @param cardNumber
     * @return
     */
    private static String calculateVerifyCode(CharSequence cardNumber) {
        int sum = 0;
        for (int i = 0; i < NEW_CARD_NUMBER_LENGTH - 1; i++) {
            char ch = cardNumber.charAt(i);
            sum += ((int) (ch - '0')) * Integer.parseInt(Wi[i]);
        }
        return ValCodeArr[sum % 11];
    }

    /**
     * 功能：设置地区编码
     *
     * @return Hashtable 对象
     */
    private static Hashtable<String, String> GetAreaCode() {
        Hashtable<String, String> hashtable = new Hashtable<String, String>();
        hashtable.put("11", "北京");
        hashtable.put("12", "天津");
        hashtable.put("13", "河北");
        hashtable.put("14", "山西");
        hashtable.put("15", "内蒙古");
        hashtable.put("21", "辽宁");
        hashtable.put("22", "吉林");
        hashtable.put("23", "黑龙江");
        hashtable.put("31", "上海");
        hashtable.put("32", "江苏");
        hashtable.put("33", "浙江");
        hashtable.put("34", "安徽");
        hashtable.put("35", "福建");
        hashtable.put("36", "江西");
        hashtable.put("37", "山东");
        hashtable.put("41", "河南");
        hashtable.put("42", "湖北");
        hashtable.put("43", "湖南");
        hashtable.put("44", "广东");
        hashtable.put("45", "广西");
        hashtable.put("46", "海南");
        hashtable.put("50", "重庆");
        hashtable.put("51", "四川");
        hashtable.put("52", "贵州");
        hashtable.put("53", "云南");
        hashtable.put("54", "西藏");
        hashtable.put("61", "陕西");
        hashtable.put("62", "甘肃");
        hashtable.put("63", "青海");
        hashtable.put("64", "宁夏");
        hashtable.put("65", "新疆");
        hashtable.put("71", "台湾");
        hashtable.put("81", "香港");
        hashtable.put("82", "澳门");
        hashtable.put("91", "国外");
        return hashtable;
    }

    private static Date getBirthDate(String idcard) {
        Date cacheBirthDate=null;
        try {
            cacheBirthDate = createBirthDateParser().parse(getBirthDayPart(idcard));
        } catch (Exception e) {
            throw new RuntimeException("身份证的出生日期无效");
        }
        return new Date(cacheBirthDate.getTime());
    }

    private static SimpleDateFormat createBirthDateParser() {
        return new SimpleDateFormat(BIRTH_DATE_FORMAT);
    }

    private static String getBirthDayPart(String idcardnumber) {
        return idcardnumber.substring(6, 14);
    }

    //两张图片合成
    public static Bitmap mergeThumbnailBitmap(Bitmap firstBitmap, Bitmap secondBitmap) {
        //以其中一张图片的大小作为画布的大小，或者也可以自己自定义
        Bitmap bitmap = Bitmap.createBitmap(firstBitmap.getWidth(), firstBitmap
                .getHeight(), firstBitmap.getConfig());
        //生成画布
        Canvas canvas = new Canvas(bitmap);
        //因为我传入的secondBitmap的大小是不固定的，所以我要将传来的secondBitmap调整到和画布一样的大小
        Matrix m = new Matrix();
        //确定secondBitmap大小比例
        m.postScale(((float)720)/secondBitmap.getWidth(),((float)540)/secondBitmap.getHeight());
        canvas.drawBitmap(firstBitmap,0,0,null);
        canvas.drawBitmap(secondBitmap,m,null);
        return bitmap;
    }

    /**
     * 获得当前进程的名字
     *
     * @param context
     * @return 进程号
     */
    public static String getCurProcessName(Context context) {

        int pid = android.os.Process.myPid();

        ActivityManager activityManager = (ActivityManager) context
                .getSystemService(Context.ACTIVITY_SERVICE);

        for (ActivityManager.RunningAppProcessInfo appProcess : activityManager
                .getRunningAppProcesses()) {

            if (appProcess.pid == pid) {
                return appProcess.processName;
            }
        }
        return null;
    }

    /**
     * view转bitmap
     * @param view_now
     * @return
     */
    public static Bitmap getActivityBitmap(View view_now) {

        View view = view_now;
        view.buildDrawingCache();
        int widths = view.getWidth();
        int heights = view.getHeight();
        view.setDrawingCacheEnabled(true);
        Bitmap bmp = Bitmap.createBitmap(view.getDrawingCache(), 0, 0, widths, heights);
        view.destroyDrawingCache();
        return bmp;
    }

    /**
     * 获取是否存在NavigationBar
     * @param context
     * @return
     */
    public static boolean checkDeviceHasNavigationBar(Context context) {

        boolean hasNavigationBar = false;
        Resources rs = context.getResources();
        int id = rs.getIdentifier("config_showNavigationBar", "bool", "android");
        if (id > 0) {
            hasNavigationBar = rs.getBoolean(id);
        }
        try {
            Class systemPropertiesClass = Class.forName("android.os.SystemProperties");
            Method m = systemPropertiesClass.getMethod("get", String.class);
            String navBarOverride = (String) m.invoke(systemPropertiesClass, "qemu.hw.mainkeys");
            if ("1".equals(navBarOverride)) {
                hasNavigationBar = false;
            } else if ("0".equals(navBarOverride)) {
                hasNavigationBar = true;
            }
        } catch (Exception e) {
        }
        return hasNavigationBar;
    }

    /**
     * 隐藏虚拟按键，并且全屏
     */
    public static void hideBottomUIMenu(Activity activity) {
        //隐藏虚拟按键，并且全屏
        if (Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT < 19) { // lower api
            View v = activity.getWindow().getDecorView();
            v.setSystemUiVisibility(View.GONE);
        } else if (Build.VERSION.SDK_INT >= 19) {
            //for new api versions.
            View decorView = activity.getWindow().getDecorView();
            int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_FULLSCREEN;
            decorView.setSystemUiVisibility(uiOptions);
        }
    }

    /**
     * 设置沉浸式状态栏
     * @param activity
     */
    @TargetApi(Build.VERSION_CODES.KITKAT)
    public static void initStateView(Activity activity) {

        if (activity == null){
            return;
        }

        if (Build.VERSION.SDK_INT  > Build.VERSION_CODES.KITKAT) {

            activity.getWindow().getDecorView().setFitsSystemWindows(true);
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }
    }

    public static int getStatusBarHeight(Activity activity) {

        int result = 0;
        int resourceId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = activity.getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    }

    /**
     * 获取设备ip地址
     */
    public static String getIp(Activity activity){

        //获取wifi服务
        WifiManager wifiManager = (WifiManager) activity.getApplicationContext().getSystemService(Context.WIFI_SERVICE);

        //判断wifi是否开启
        if (wifiManager.isWifiEnabled()) {

            WifiInfo wifiInfo = wifiManager.getConnectionInfo();

            int ipAddress = wifiInfo.getIpAddress();

            String ip = intToIp(ipAddress);

            return ip;
        }else {

            try {

                for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {

                    NetworkInterface intf = en.nextElement();

                    for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {

                        InetAddress inetAddress = enumIpAddr.nextElement();

                        if (!inetAddress.isLoopbackAddress()){

                            return inetAddress.getHostAddress();
                        }
                    }
                }
            }
            catch (SocketException ex){

            }
        }

        return null;
    }

    private static String intToIp(int i) {

        return (i & 0xFF ) + "." +
                ((i >> 8 ) & 0xFF) + "." +
                ((i >> 16 ) & 0xFF) + "." +
                ( i >> 24 & 0xFF) ;
    }
}
